package com.pww.movie.controller;

import com.pww.movie.domain.PO.Media;
import com.pww.movie.mapper.MediaMapper;
import com.pww.movie.utils.Result;
import com.pww.movie.utils.ThreadLocalUtil;
import com.pww.movie.utils.UploadBase64Image2MinioUtil;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.pww.movie.utils.MinioUploadUtil;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;

/**
 * @author panweiwei
 */
@AllArgsConstructor
@RestController
@RequestMapping("/file")
public class FileController {

    private final MinioClient minioClient;

    private final MinioUploadUtil minioUploadUtil;

    private final MediaMapper mediaMapper;

    private final String BUCKET_NAME = "dairy-minio";

    private final String ENDPOINT = "http://192.168.31.181:9000";

    private final UploadBase64Image2MinioUtil uploadBase64Image2MinioUtil;

    /**
     * 初始化桶，如果桶不存在则创建
     */

    @PostConstruct
    public void initBucket() throws Exception {
        minioUploadUtil.initBucket(minioClient, BUCKET_NAME);
    }

    /**
     * 上传文件到MinIO
     *
     * @param file 要上传的文件
     * @return 上传结果的URL或错误信息
     */
    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
            return "上传成功，访问地址：" + MinioUploadUtil.uploadFile(minioClient, BUCKET_NAME, file, fileName, ENDPOINT);
        } catch (Exception e) {
            e.printStackTrace();
            return "上传失败：" + e.getMessage();
        }
    }

    /**
     * 上传视频文件并转码为m3u8格式后存储到MinIO服务器。
     *
     * @param file 待上传的视频文件
     * @return 返回m3u8文件的访问地址或错误信息
     */
    @PostMapping("/upload-m3u8")
    public Result uploadM3u8(@RequestParam("file") MultipartFile file,
                             @RequestParam(required = true) String title,
                             @RequestParam(required = true) String type,
                             @RequestParam(required = true) Boolean isBanner,
                             @RequestParam(required = true) Integer createId,
                             @RequestParam(required = false) String description,
                             @RequestParam(required = false) String coverImage  // 添加封面参数 MultipartFile file
    ) {
        String coverUrl = null;
        String tempDir = System.getProperty("java.io.tmpdir") + "/m3u8_" + System.currentTimeMillis();
        java.io.File tempDirFile = new java.io.File(tempDir);
        if (!tempDirFile.exists()) {
            tempDirFile.mkdirs();
        }
        String originalFileName = file.getOriginalFilename();
        String localVideoPath = tempDir + "/" + originalFileName;
        // 生成唯一英文名（UUID）作为m3u8和ts文件前缀，避免中文和特殊字符
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String videoExt = originalFileName.contains(".") ? originalFileName.substring(originalFileName.lastIndexOf('.')) : "";
        String safeBaseName = uuid;
        String m3u8Name = safeBaseName + ".m3u8";
        String localM3u8Path = tempDir + "/" + m3u8Name;
        try {
            // 保存原始视频到本地
            file.transferTo(new java.io.File(localVideoPath));
            // 转码为m3u8，ts分片也会自动用safeBaseName+数字.ts命名
            String ffmpegCmd = String.format(
                    "export PATH=$PATH:/Users/panweiwei/Downloads && ffmpeg -i '%s' -codec: copy -start_number 0 -hls_time 6 -hls_list_size 0 -hls_segment_filename '%s/%s_%%03d.ts' -f hls '%s'",
                    localVideoPath, tempDir, safeBaseName, localM3u8Path
            );
            Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", ffmpegCmd});
            int exitCode = process.waitFor();
            if (exitCode != 0) {
                return Result.error("FFmpeg转码失败");
            }
            // 上传m3u8及ts文件到minio
            String minioDir = "hls/" + System.currentTimeMillis() + "/";
            String m3u8Url = minioUploadUtil.uploadDir(minioClient, BUCKET_NAME, tempDir, minioDir, ENDPOINT);
            if (coverImage != null) {
                try {
                    coverUrl = uploadBase64Image2MinioUtil.uploadBase64Image2Minio(coverImage, BUCKET_NAME, ENDPOINT);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            Media media = new Media();
            media.setType(type);
            media.setUrl(m3u8Url);
            media.setTitle(title);
            media.setCreatorId(createId.longValue());
            media.setDescription(description);
            media.setIsBanner(isBanner);
            media.setDeleted(false);
            media.setCreatedTime(LocalDateTime.now());
            media.setCoverImage(coverUrl);
            mediaMapper.insert(media);
            System.out.println("上传成功，m3u8访问地址：" + m3u8Url);
            return Result.success("上传成功，m3u8访问地址：" + m3u8Url);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("上传失败：" + e.getMessage());
        } finally {
            // 可选：清理临时文件
        }
    }


}
